
import { _decorator, Component, instantiate, Node,sp, tween, Vec2,Vec3  } from 'cc';
import { CharactorData } from './CharactorCtrl';
import { AppLauncher } from './AppLauncher';
const { ccclass, property } = _decorator;

var LineupPos = [
    { x : -145 , y : -150},
    { x : -350 , y : -145},
    { x : -220 , y : -220},
    { x : -410 , y : -255},
    { x : -290 , y : -330},
]

export type AttackTarget = {
    targetId : number,
    effectId : number,
    value : number,
    fieldType : number,
    flag : number,
    round : number,
}; 

export type AttackReport = {
    atkId : number,
    vTarget : AttackTarget[],
    atkSkillId : number
};

export type BattleRoundReport = {
    atkReport : AttackReport[]
}

export type BattleReport = {
    isRedWin : boolean,
    roundCount : number,
    vReport : BattleRoundReport[]
}

export type BattleLineupData = {
    blueLineup : CharactorData[],
    redLineup : CharactorData[],
}

type IndexAndLineupType = {
    index : number,
    lineup : number
}

@ccclass('BattleSceneCtrl')
export class BattleSceneCtrl extends Component {

    battleReport : BattleReport = null;
    battleLineup : BattleLineupData = null;

    private leftCharacters : Node[] = [];
    private rightCharacters : Node[] = [];

    private mapCharactorByUid : Map<number,IndexAndLineupType> = null

    private curRound = 0

    private vAttackReport : AttackReport[] = [];

    private curAttackIndex = 0

    protected onLoad(): void {
    }

    start () {
       
    }

    InitBattleReport(report : BattleReport){
        this.battleReport = report;
        console.log(this.battleReport);
    }

    SetBattleLineup(lineup : BattleLineupData){
        this.battleLineup = lineup;
        console.log(this.battleLineup);
    }    

    InitDataBeforeStart(){
        this.mapCharactorByUid = new Map();

        //初始化蓝色阵容
        for (var i = 0; i < 5; i++) {
            this.leftCharacters[i] = instantiate(AppLauncher.Instance.Charactor)
            this.leftCharacters[i].setPosition(LineupPos[i].x,LineupPos[i].y)
            AppLauncher.Instance.Canvas.addChild(this.leftCharacters[i])
            this.leftCharacters[i].getComponent(sp.Skeleton).skeletonData = AppLauncher.Instance.SkeletonDatas[i];
            this.leftCharacters[i].getComponent(sp.Skeleton).animation = "Idle"
            
            this.leftCharacters[i].getComponent("CharactorCtrl").setCharactorData(this.battleLineup.blueLineup[i])
            this.mapCharactorByUid[this.battleLineup.blueLineup[i].uid] = {
                index : i,
                lineup : 0, 
            };
        }

        //初始化红色阵容
        for (var i = 0; i < 5; i++) {
            this.rightCharacters[i] = instantiate(AppLauncher.Instance.Charactor)
            this.rightCharacters[i].setPosition(-LineupPos[i].x,LineupPos[i].y)
            AppLauncher.Instance.Canvas.addChild(this.rightCharacters[i])

            var originScale = this.rightCharacters[i].scale
            this.rightCharacters[i].setScale(new Vec3(-originScale.x, originScale.y, originScale.z))
            this.rightCharacters[i].getChildByName("HarmValueText").setScale(originScale)

            this.rightCharacters[i].getComponent(sp.Skeleton).skeletonData = AppLauncher.Instance.SkeletonDatas[i+5];
            this.rightCharacters[i].getComponent(sp.Skeleton).animation = "Idle"

            this.rightCharacters[i].getComponent("CharactorCtrl").setCharactorData(this.battleLineup.redLineup[i])
            this.mapCharactorByUid[this.battleLineup.redLineup[i].uid] = {
                index : i,
                lineup : 1, 
            };
        }
    }

    StartBattle(){
        this.InitDataBeforeStart();

        for(let i=0;i<this.battleReport.roundCount;++i){
            for(let j=0;j<this.battleReport.vReport[i].atkReport.length;++j){
                this.vAttackReport.push(this.battleReport.vReport[i].atkReport[j])
            }
        }

        console.log(this.vAttackReport);

        this.StartAction(this.vAttackReport[this.curAttackIndex++])
    }

    StartAction(report : AttackReport){
        if(report == null){
            return ;
        }
        let target = report.vTarget[0];

        var targetCallback = function() {
            for(let i=0;i<report.vTarget.length;++i){
                this.TargetAction(report.vTarget[i])
            }

            if(this.curAttackIndex < this.vAttackReport.length){
                this.StartAction(this.vAttackReport[this.curAttackIndex++]);
            }
            else
            {
                console.log("battle end")
            }
        }.bind(this)

        if(report.atkId != 0)
        {
            let atkCharactor = this.FindCharactorByUid(report.atkId)
            let targetCharactor = this.FindCharactorByUid(target.targetId)
            let atkOriginPos = atkCharactor.getPosition()
            var callback = function() {
                this.AtkAction(report.atkId,report.atkSkillId,targetCallback,atkOriginPos);
            }.bind(this)
            tween(atkCharactor).to(0.5, {position: new Vec3(targetCharactor.getPosition().x,
                targetCharactor.getPosition().y,0)}).call(callback).start();
        }
        else
        {
            targetCallback();
        }
    }

    AtkAction(atkId : number , atkSkillId : number ,targetCallback : any,atkOriginPos : Vec3){
        console.log("attackId: ",atkId," skill: ",atkSkillId);
        let atkCharactor = this.FindCharactorByUid(atkId)
        this.SetAnimation(atkCharactor,"Attack",()=>{
            this.SetAnimation(atkCharactor,"Run",()=>{});

            var callback = function() {
                this.SetAnimation(atkCharactor,"Idle",()=>{});
                targetCallback();
            }.bind(this)
            tween(atkCharactor).to(0.5, {position: new Vec3(atkOriginPos)}).call(callback).start();    
        });
    }

    SetAnimation(charactor : Node ,animation : any, callback : any){
        charactor.getComponent(sp.Skeleton).animation = animation;
        charactor.getComponent(sp.Skeleton).setCompleteListener((trackEntry : sp.spine.TrackEntry)=>{
            callback();
        }); 
    }

    TargetAction(report : AttackTarget){
        console.log("defId: ",report.targetId," effect: ",report.effectId," value: ",report.value," round: ",report.round);
    
        //charactor
        let character : Node = this.FindCharactorByUid(report.targetId);
        if(character == null){
            return
        }

        if(report.fieldType == 1)
        {
            let characterData : CharactorData= character.getComponent("CharactorCtrl").charactorData;
            characterData.curHp -= report.value;
            if(characterData.curHp <= 0){
                characterData.curHp = 0
                character.getComponent("CharactorCtrl").setBloodVisible(false)
                this.SetAnimation(character,"Die",()=>{
                    character.active = false
                    character = null;
                });
                return ;
            }
            else if(characterData.curHp > characterData.maxHp){
                characterData.curHp = characterData.maxHp
            }
            //harm animation
            character.getComponent("CharactorCtrl").setHarmValue(-report.value)
            setTimeout(()=>{
                character.getComponent("CharactorCtrl").setHarmValueVisble(false)
            },200);

            console.log("fillRange: ",characterData.curHp/characterData.maxHp," curHp: ",characterData.curHp," maxHp: ",characterData.maxHp)
            character.getComponent("CharactorCtrl").setBlood(characterData.curHp/characterData.maxHp)       
        }
    }

    FindCharactorByUid(uid : number){
        let character : Node = null
        let index : IndexAndLineupType = this.mapCharactorByUid[uid];
        if(index.lineup == 0)
        {
            character = this.leftCharacters[index.index];
        }
        else
        {
            character = this.rightCharacters[index.index];
        }
        return character;
    }
}
